package zookeeper.curator;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.junit.Test;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class CuratorBaseOperations extends CuratorStandaloneBase {
  /**
   * 递归创建子节点
   */
  @Test
  public void testCreateWithParent() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();

    String pathWithParent = "/node-parent/sub-node-1";
    String path = curatorFramework.create().creatingParentContainersIfNeeded().forPath(pathWithParent);
    log.info("curator create node:{} successfully.", path);
  }

  /**
   * protection模式 防止由于异常原因，导致僵尸节点
   */
  @Test
  public void testCreate() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();
    String forPath = curatorFramework.create()
        // 保持幂等性数据一致性
        .withProtection()
        // 顺序临时节点
        .withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/curator-node", "some-data".getBytes());
    log.info("curator create node:{} successfully.", forPath);
  }

  @Test
  public void testGetData() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();

    byte[] bytes = curatorFramework.getData().forPath("curator-node");
    log.info("get data from node:{} successfully.", new String(bytes));
  }

  @Test
  public void testSetData() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();

    curatorFramework.setData().forPath("curator-node", "changed!".getBytes());
    byte[] bytes = curatorFramework.getData().forPath("/curator-node");
    log.info("get data from node /curator-node:{} successfully.", new String(bytes));
  }

  @Test
  public void testDelete() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();

    String pathWithParent = "/node-parent";
    curatorFramework.delete()
        // 保证删除成功 网络原因会重试
        .guaranteed().deletingChildrenIfNeeded().forPath(pathWithParent);
  }

  @Test
  public void testListChildren() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();

    String pathWithParent = "/discovery/example";
    List<String> strings = curatorFramework.getChildren().forPath(pathWithParent);
    strings.forEach(System.out::println);
  }

  @Test
  public void testThreadPool() throws Exception {
    CuratorFramework curatorFramework = getCuratorFramework();
    // curator支持自定义线程池 而不是在原来的event-thread执行
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    String ZK_NODE = "/zk-node";
    curatorFramework.getData().inBackground((client, event) -> log.info("background:{}", event), executorService).forPath(ZK_NODE);
  }
}
